
local lvbuwei = General(extension, "lingling__lvbuwei", "qin", 3)
local qihuo = fk.CreateTriggerSkill{
  name = "lingling__qihuo",
  anim_type = "special",
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and not player:isNude()
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local tos, cards = room:askForChooseCardsAndPlayers(player, 1, 2, table.map(room.alive_players, Util.IdMapper), 1, 1, nil,
      "#lingling__qihuo-invoke", self.name, true, false)
    if #tos == 1 and #cards > 0 then
      self.cost_data = {tos = tos, cards = cards}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data.tos[1])
    room:setPlayerMark(player, self.name, {to.id, self.cost_data.cards})
    to:addToPile("$lingling__qihuo", self.cost_data.cards, false, self.name, player.id, {})
    if not to.dead and not player.dead and not to:isNude() and to ~= player then
      local cards = room:askForCard(to, 1, 999, true, self.name, false, nil, "#lingling__qihuo-give:"..player.id)
      room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonGive, self.name, nil, false, to.id)
    end
  end,
}
local qihuo_delay = fk.CreateTriggerSkill{
  name = "#lingling__qihuo_delay",
  mute = true,
  events = {fk.Damaged, fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    if event == fk.Damaged then
      return #target:getPile("$lingling__qihuo") > 0
    elseif event == fk.TurnStart then
      return target == player and player:getMark("lingling__qihuo") ~= 0
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == fk.Damaged then
      if player:getMark("lingling__qihuo")[1] == target.id then
        player:broadcastSkillInvoke("lingling__qihuo")
        room:notifySkillInvoked(player, "lingling__qihuo", "negative")
      end
      room:moveCardTo(target:getPile("$lingling__qihuo"), Card.DiscardPile, nil, fk.ReasonPutIntoDiscardPile,
        "lingling__qihuo", nil, true)
    elseif event == fk.TurnStart then
      local to = room:getPlayerById(player:getMark("lingling__qihuo")[1])
      if to.dead then return end
      local cards = table.filter(to:getPile("$lingling__qihuo"), function (id)
        return table.contains(player:getMark("lingling__qihuo")[2], id)
      end)
      if #cards == 0 then return end
      player:broadcastSkillInvoke("lingling__qihuo")
      room:notifySkillInvoked(player, "lingling__qihuo", "drawcard")
      room:moveCardTo(cards, Card.DiscardPile, nil, fk.ReasonPutIntoDiscardPile, "lingling__qihuo", nil, true)
      if player.dead then return end
      player:drawCards(2 * #cards, "lingling__qihuo")
      if player.dead then return end
      if player.maxHp < 6 then
        room:changeMaxHp(player, 1)
        if player.dead then return end
      end
      if player:isWounded() then
        room:recover{
          who = player,
          num = 1,
          recoverBy = player,
          skillName = "lingling__qihuo",
        }
      end
    end
  end,
}
local huisheng = fk.CreateTriggerSkill{
  name = "lingling__huisheng",
  anim_type = "defensive",
  events = {fk.DamageCaused},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target and target ~= player and #player:getCardIds("he") > 1 and not target.dead
  end,
  on_cost = function (self, event, target, player, data)
    local cards = player.room:askForCard(player, 2, 2, true, self.name, true, nil,
      "#lingling__huisheng-give:"..target.id..":"..data.to.id)
    if #cards > 0 then
      self.cost_data = {tos = {target.id}, cards = cards}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:moveCardTo(self.cost_data.cards, Card.PlayerHand, target, fk.ReasonGive, self.name, nil, false, player.id)
    return true
  end,
}
Fk:loadTranslationTable{
  ["lingling__lvbuwei"] = "吕不韦",
  ["#lingling__lvbuwei"] = "悬金钓奇",
  ["designer:lingling__lvbuwei"] = "伶",

  ["lingling__qihuo"] = "奇货",
  [":lingling__qihuo"] = "回合结束时，你可以将至多两张牌扣置于一名角色武将牌旁，其交给你至少一张牌。当其受到伤害后移去这些牌，"..
  "下回合开始时，若这些牌未移去，你移去这些牌摸两倍的牌、加1点体力上限并回复1点体力（至多加至6）。",
  ["lingling__huisheng"] = "贿生",
  [":lingling__huisheng"] = "当一名角色造成伤害时，你可以交给伤害来源两张牌防止之。"..
  "<br><br> <font color = '#a40000'>十年富贵随轻覆，奇货元来祸更奇。",
  ["#lingling__qihuo-invoke"] = "奇货：将至多两张牌扣置为一名角色的“奇货”牌",
  ["$lingling__qihuo"] = "奇货",
  ["#lingling__qihuo-give"] = "奇货：交给 %src 至少一张牌",
  ["#lingling__qihuo_delay"] = "奇货",
  ["#lingling__huisheng-give"] = "贿生：是否交给 %src 两张牌，防止其对 %dest 造成的伤害？",
}

local zhanghan = General(extension, "lingling__zhanghan", "qin", 4)
local duzhu = fk.CreateTriggerSkill{
  name = "lingling__duzhu",
  anim_type = "special",
  frequency = Skill.Limited,
  events = {fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryGame) == 0 and
      #player.room:getOtherPlayers(player) > 0
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#lingling__duzhu-invoke")
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:doIndicate(player.id, table.map(room:getOtherPlayers(player), Util.IdMapper))
    for _, p in ipairs(room:getOtherPlayers(player)) do
      if player.dead then return end
      if not p.dead then
        local choice = room:askForChoice(p, {"lingling__duzhu_damage:"..player.id, "lingling__duzhu_draw:"..player.id}, self.name)
        if choice:startsWith("lingling__duzhu_damage") then
          room:damage{
            from = p,
            to = player,
            damage = 1,
            skillName = self.name,
          }
        else
          player:drawCards(2, self.name)
        end
      end
    end
  end,
}
local wanlan = fk.CreateTriggerSkill{
  name = "lingling__wanlan",
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  events = {fk.Damage, fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      local n = 0
      if event == fk.Damage then
        n = #player.room.logic:getActualDamageEvents(4, function(e)
          return e.data[1].from == player
        end, Player.HistoryTurn)
      elseif event == fk.Damaged then
        n = #player.room.logic:getActualDamageEvents(4, function(e)
          return e.data[1].to == player
        end, Player.HistoryTurn)
      end
      self.cost_data = n
      if n == 2 then
        return true
      elseif n == 3 then
        return player:isWounded()
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if self.cost_data == 2 then
      player:drawCards(1, self.name)
    elseif self.cost_data == 3 then
      room:recover{
        who = player,
        num = 1,
        recoverBy = player,
        skillName = self.name,
      }
    end
  end,
}
local pingpan = fk.CreateTriggerSkill{
  name = "lingling__pingpan",
  anim_type = "offensive",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Play
  end,
  on_cost = function(self, event, target, player, data)
    local choice = player.room:askForChoice(player, {"lingling__pingpan1", "lingling__pingpan2", "Cancel"}, self.name,
      "#lingling__pingpan-choice")
    if choice ~= "Cancel" then
      self.cost_data = {choice = choice}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(player, "@@"..self.cost_data.choice.."-turn", 1)
    if self.cost_data.choice == "lingling__pingpan2" then
      room:addPlayerMark(player, MarkEnum.SlashResidue.."-turn", 1)
    end
  end,

  refresh_events = {fk.Damaged},
  can_refresh = function (self, event, target, player, data)
    return target == player and player:hasSkill(self, true) and data.from
  end,
  on_refresh = function (self, event, target, player, data)
    player.room:addTableMark(player, self.name, data.from.id)
  end,

  on_acquire = function (self, player, is_start)
    local room = player.room
    local targets = {}
    room.logic:getActualDamageEvents(1, function(e)
      local damage = e.data[1]
      if damage.to == player and damage.from then
        table.insertIfNeed(targets, damage.from.id)
      end
    end, Player.HistoryGame)
    room:setPlayerMark(player, self.name, targets)
  end,
}
local pingpan_delay = fk.CreateTriggerSkill{
  name = "#lingling__pingpan_delay",
  anim_type = "offensive",
  events = {fk.AfterCardTargetDeclared, fk.Deathed},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(pingpan) then
      if event == fk.AfterCardTargetDeclared and target == player then
        return target == player and data.card.trueName == "slash" and
          player:getMark("@@lingling__pingpan1-turn") + player:getMark("@@lingling__pingpan2-turn") > 0 and
          table.find(player.room:getUseExtraTargets(data, true), function (id)
            return table.contains(player:getTableMark("lingling__pingpan"), id)
          end)
      elseif event == fk.Deathed and player:usedSkillTimes("lingling__pingpan", Player.HistoryPhase) > 0 then
        return data.damage and data.damage.from and data.damage.from == player and
          data.damage.card and data.damage.card.trueName == "slash"
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.AfterCardTargetDeclared then
      local room = player.room
      local targets = table.filter(room:getUseExtraTargets(data, true), function (id)
        return table.contains(player:getTableMark("lingling__pingpan"), id)
      end)
      local n = player:getMark("@@lingling__pingpan1-turn") > 0 and 10 or 1
      local tos = room:askForChoosePlayers(player, targets, 1, n,
        "#lingling__pingpan-choose:::"..data.card:toLogString(), "lingling__pingpan", true)
      if #tos > 0 then
        self.cost_data = {tos = tos}
        return true
      end
    elseif event == fk.Deathed then
      self.cost_data = nil
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    if event == fk.AfterCardTargetDeclared then
      table.insertTable(data.tos, table.map(self.cost_data.tos, function (id)
        return {id}
      end))
    elseif event == fk.Deathed then
      local room = player.room
      room:setPlayerMark(player, "@@lingling__pingpan1-turn", 0)
      room:setPlayerMark(player, "@@lingling__pingpan2-turn", 0)
      room:invalidateSkill(player, "lingling__pingpan", "-turn")
      if player.maxHp < 6 then
        room:changeMaxHp(player, 1)
      end
      if player:isWounded() and not player.dead then
        room:recover{
          who = player,
          num = 1,
          recoverBy = player,
          skillName = "lingling__pingpan",
        }
      end
    end
  end,
}
local pingpan_targetmod = fk.CreateTargetModSkill{
  name = "#lingling__pingpan_targetmod",
  main_skill = pingpan,
  bypass_distances =  function(self, player, skill)
    return player:hasSkill(pingpan) and skill.trueName == "slash_skill"
  end,
}
Fk:loadTranslationTable{
  ["lingling__zhanghan"] = "章邯",
  ["#lingling__zhanghan"] = "再造大秦",
  ["illustrator:lingling__zhanghan"] = "珊瑚虫",
  ["designer:lingling__zhanghan"] = "伶",

  ["lingling__duzhu"] = "独柱",
  [":lingling__duzhu"] = "限定技，回合开始时，你可以令其他角色依次选择：对你造成1点伤害；令你摸两张牌。",
  ["lingling__wanlan"] = "挽澜",
  [":lingling__wanlan"] = "你每回合：第二次受到或造成伤害后，你摸一张牌；第三次受到或造成伤害后，你回复1点体力。",
  ["lingling__pingpan"] = "平叛",
  [":lingling__pingpan"] = "你使用【杀】无距离限制。出牌阶段开始时，你可以选择令你本回合使用【杀】：可以额外指定任意名对你造成过伤害的角色"..
  "为目标；可以额外指定一名对你造成过伤害的角色为目标，且本回合你使用【杀】的次数上限+1。因此杀死一名角色后，你加1点体力上限并回复1点体力"..
  "（至多加至6），然后本回合此技能无效。"..
  "<br><br> <font color = '#a40000'>盖章邯为秦之骁将，邯不败，即秦不亡。",
  ["#lingling__duzhu-invoke"] = "独柱：是否令其他角色依次选择：对你造成1点伤害，或令你摸两张牌？",
  ["lingling__duzhu_damage"] = "对 %src 造成1点伤害",
  ["lingling__duzhu_draw"] = "%src 摸两张牌",
  ["#lingling__pingpan-choice"] = "平叛：你可以选择一项本回合生效",
  ["lingling__pingpan1"] = "使用【杀】额外指定任意名对你造成过伤害的角色为目标",
  ["lingling__pingpan2"] = "使用【杀】额外指定一名对你造成过伤害的角色为目标，次数上限+1",
  ["@@lingling__pingpan1-turn"] = "平叛 任意额外目标",
  ["@@lingling__pingpan2-turn"] = "平叛 一名额外目标",
  ["#lingling__pingpan_delay"] = "平叛",
  ["#lingling__pingpan-choose"] = "平叛：你可以为此%arg额外指定对你造成过伤害的角色为目标",

  ["$lingling__duzhu1"] = "待令严守关中，山东已无王臣。",
  ["$lingling__duzhu2"] = "废怠堕之将，战事或有胜机！",
}

local wangjian = General(extension, "lingling__wangjian", "qin", 4)
local chizhong = fk.CreateTriggerSkill{
  name = "lingling__chizhong",
  anim_type = "control",
  events = {fk.TargetSpecified, fk.TargetConfirmed, fk.StartPindian},
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) then return end
    if event == fk.TargetSpecified or event == fk.TargetConfirmed then
      if target == player and data.card.trueName == "slash" and not player:isNude() then
        if event == fk.TargetSpecified then
          return data.to ~= player.id
        elseif event == fk.TargetConfirmed then
          return data.from ~= player.id
        end
      end
    elseif event == fk.StartPindian and #player:getCardIds("e") > 0 then
      if player == data.from then
        return not data.fromCard
      elseif data.results[player.id] then
        return not data.results[player.id].toCard
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    if event == fk.TargetSpecified or event == fk.TargetConfirmed then
      local to = event == fk.TargetConfirmed and data.from or data.to
      local cards = room:askForDiscard(player, 1, 999, true, self.name, true, nil,
        "#lingling__chizhong-invoke::"..to, true)
      if #cards > 0 then
        self.cost_data = {tos = {to}, cards = cards}
        return true
      end
    elseif event == fk.StartPindian then
      local cancelable = not player:isKongcheng()
      local card = room:askForCard(player, 1, 1, true, self.name, cancelable, ".|.|.|equip", "#lingling__chizhong-pindian")
      if #card > 0 then
        self.cost_data = {cards = card}
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TargetSpecified or event == fk.TargetConfirmed then
      room:throwCard(self.cost_data.cards, self.name, player, player)
      local to = room:getPlayerById(self.cost_data.tos[1])
      if player.dead or to.dead or to:isKongcheng() then return end
      local ignoreFromKong = #player:getCardIds("e") > 0
      if not player:canPindian(to, ignoreFromKong) then return end
      local pindian = {
        from = player,
        tos = {to},
        reason = self.name,
        fromCard = nil,
        results = {},
        extra_data = {
          lingling__chizhong = #self.cost_data.cards,
        },
      }
      room:pindian(pindian)
      local winner = pindian.results[to.id].winner
      if winner and not winner.dead and winner:getHandcardNum() < 4 then
        winner:drawCards(4 - winner:getHandcardNum(), self.name)
      end
    elseif event == fk.StartPindian then
      local card = Fk:getCardById(self.cost_data.cards[1])
      if player == data.from then
        data.fromCard = card
      else
        data.results[player.id].toCard = card
      end
    end
  end,

  refresh_events = {fk.PindianCardsDisplayed},
  can_refresh = function (self, event, target, player, data)
    return data.reason == self.name and data.results[player.id] and data.extra_data and data.extra_data.lingling__chizhong
  end,
  on_refresh = function (self, event, target, player, data)
    data.results[player.id].toCard.number = math.max(1, data.results[player.id].toCard.number - data.extra_data.lingling__chizhong)
  end,
}
local qinwang = fk.CreateTriggerSkill{
  name = "lingling__qinwang",
  anim_type = "control",
  events = {fk.Damage},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card and data.card.trueName == "slash" and
      not data.to.dead and not data.to:isKongcheng()
  end,
  on_cost = function(self, event, target, player, data)
    if player.room:askForSkillInvoke(player, self.name, nil, "#lingling__qinwang-invoke::"..data.to.id) then
      self.cost_data = {tos = {data.to.id}}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    data.to:showCards(data.to:getCardIds("h"))
    if player.dead or data.to.dead then return end
    local cards = table.filter(data.to:getCardIds("he"), function (id)
      return Fk:getCardById(id).number > 7
    end)
    if #cards > 0 then
      if data.to ~= player then
        room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonPrey, self.name, nil, false, player.id)
      end
    else
      if player.maxHp < 6 then
        room:changeMaxHp(player, 1)
        if player.dead then return end
      end
      if player:isWounded() then
        room:recover{
          who = player,
          num = 1,
          recoverBy = player,
          skillName = self.name,
        }
      end
    end
  end,
}
Fk:loadTranslationTable{
  ["lingling__wangjian"] = "王翦",
  ["#lingling__wangjian"] = "功盖六国",
  ["illustrator:lingling__wangjian"] = "珊瑚虫",
  ["designer:lingling__wangjian"] = "伶",

  ["lingling__chizhong"] = "持重",
  [":lingling__chizhong"] = "当你使用【杀】指定目标后，或其他角色使用【杀】指定你为目标后，你可以弃置任意张牌，然后与其拼点，"..
  "其此次拼点牌的点数-X（X为你弃牌数），赢者摸牌至四张。你可以用装备区的牌拼点。",
  ["lingling__qinwang"] = "擒王",
  [":lingling__qinwang"] = "当你使用【杀】造成伤害后，你可以展示其所有手牌，获得其点数大于7的所有牌，若没有点数大于7的牌，"..
  "你加1点体力上限并回复1点体力（至多加至6）。"..
  "<br><br> <font color = '#a40000'>将军料敌元非怯，能使君王促驾来。",
  ["#lingling__chizhong-invoke"] = "持重：你可以弃置任意张牌，然后与 %dest 拼点，赢者摸牌至四张",
  ["#lingling__chizhong-pindian"] = "持重：你可以用装备区的牌拼点",
  ["#lingling__qinwang-invoke"] = "擒王：是否令 %dest 展示所有手牌？",
}

local lixin = General(extension, "lingling__lixin", "qin", 4, 6)
local guozhuang = fk.CreateTriggerSkill{
  name = "lingling__guozhuang",
  mute = true,
  frequency = Skill.Compulsory,
  events = {fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(self.name)
    if player:isWounded() then
      room:notifySkillInvoked(player, self.name, "drawcard")
      room:recover{
        who = player,
        num = 1,
        recoverBy = player,
        skillName = self.name,
      }
      if not player.dead then
        player:drawCards(2, self.name)
      end
    else
      room:notifySkillInvoked(player, self.name, "negative")
    end
    if not player:isWounded() and not player.dead then
      room:handleAddLoseSkills(player, "-lingling__guozhuang", nil, true, false)
    end
  end,
}
local xingfa = fk.CreateTriggerSkill{
  name = "lingling__xingfa",
  anim_type = "offensive",
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:doIndicate(player.id, table.map(room.alive_players, Util.IdMapper))
    for _, p in ipairs(room:getAlivePlayers()) do
      if not p.dead then
        p:drawCards(1, self.name)
      end
    end
    for _, to in ipairs(room:getAlivePlayers()) do
      if not to.dead then
        local other_players = table.filter(room:getOtherPlayers(to, false), function(p) return not p:isRemoved() end)
        local luanwu_targets = table.map(table.filter(other_players, function(p2)
          return table.every(other_players, function(p1)
            return to:distanceTo(p1) >= to:distanceTo(p2)
          end)
        end), Util.IdMapper)
        local use = room:askForUseCard(to, self.name, "slash", "#lingling__xingfa-use", true, {
          bypass_times = true,
          exclusive_targets = luanwu_targets,
        })
        if use then
          if to == player then
            room:setPlayerMark(player, self.name, 0)
          end
          use.extraUse = true
          room:useCard(use)
        else
          if to == player then
            if player:getMark(self.name) > 0 then
              room:handleAddLoseSkills(player, "-lingling__xingfa", nil, true, false)
            else
              room:setPlayerMark(player, self.name, 1)
            end
          end
          room:loseHp(to, 1, self.name)
        end
      end
    end
  end,
}
lixin:addSkill(guozhuang)
lixin:addSkill(xingfa)
Fk:loadTranslationTable{
  ["lingling__lixin"] = "李信",
  ["#lingling__lixin"] = "轻狂少将",
  ["designer:lingling__lixin"] = "伶",

  ["lingling__guozhuang"] = "果壮",
  [":lingling__guozhuang"] = "回合开始时，若你已受伤，你回复1点体力并摸两张牌，若你未受伤或因此回复至满，你失去此技能。",
  ["lingling__xingfa"] = "兴伐",
  [":lingling__xingfa"] = "回合结束时，你可以令所有角色各摸一张牌，然后所有角色依次选择：对距离最近的另一名角色使用【杀】；失去1点体力。"..
  "若你连续两次选择失去1点体力，你失去此技能。"..
  "<br><br> <font color = '#a40000'>须知少时凌云志，曾许人间第一流。",
  ["#lingling__xingfa-use"] = "兴伐：你需要对距离最近的一名角色使用一张【杀】，否则失去1点体力",
}
